package com.shujia.scala

import scala.collection.mutable.ListBuffer

object Demo16ScalaList {
  /**
   * List 列表
   * 不可变的，有序的，里面的元素可以不唯一，类型必须唯一（除非将泛型指定为Any）
   */
  def main(args: Array[String]): Unit = {

    // 定义
    val list: List[Int] = List(1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4)
    println(list(2)) // 通过下标取元素
    // 常见的方法
    println(list.max) // 最大值
    println(list.min) // 最小值
    println(list.sum) // 求和
    println(list.length) // 长度
    println(list.head) // 取第一个元素
    println(list.tail) // 取除一个元素以外的所有元素
    println(list.reverse) // 反转
    println(list.distinct) // 去重
    println(list.isEmpty) // 判断是否为空
    println(list.take(5)) // 取前5个元素
    println(list.mkString(",")) // 按照指定的分隔符 将list中所有的元素与分隔符拼接并构建成字符串

    // map方法需要传入一个函数f，f的类型为： “参数类型与list的元素类型一致 返回值类型自定 "
    // 会将函数f 作用在list中的每一个元素上
    // 最后会返回一个新的list
    val list2 = list.map(_ * 2)
    println(list)
    println(list2)

    val list3: List[String] = List("hello,world,hello", "java,scala,c++", "hadoop,hbase,hive")
    for (elem <- list3.map(_.split(","))) {
      println(elem.toList)
    }

    // flatMap方法 不仅可以将传入的函数f 作用每个元素上
    // 还会对函数f返回的结果进行扁平化处理（展开）
    // 限制条件：传入的函数f的返回值类型 必须是集合类型
    // 最后会将展开后的结果以List的形式返回
    val list5: List[String] = list3.flatMap(_.split(","))
    println(list5)

    // 把list中的奇数过滤出来
    // filter方法需要传入一个函数f，函数f的返回值类型必须是Boolean类型
    // 会根据返回的是true则保留 返回false则舍弃
    println(list)
    val list6 = list.filter((i: Int) => {
      var flag = false
      if (i % 2 == 1) {
        flag = true
      }
      flag
    })
    println(list.filter(_ % 2 == 1)) // 简写方式
    println(list6)

    // foreach 需要一个输入类型同List中元素类型一致，返回值类型为Unit 这样的函数
    // println 输入类型为Any 返回值类型为Unit
    // Any是Int的父类 所以println可以直接作为foreach的函数传入
    // 同map的区别就是 一个有返回值 一个没有没有返回值
    list.foreach(println)

    // 直接排序
    val sorted: List[Int] = list.sorted
    println(sorted)

    val l1 = List(1, 2)
    val l2 = List(3, 3)
    val l3 = List(2, 1)
    val l123 = List(l1, l2, l3) // 二维List
    // 指定按照什么进行排序
    val ll = l123.sortBy(list => {
      list(1)
    })
    println(ll)

    // 指定排序的规则
    val ll2 = list.sortWith((x: Int, y: Int) => {
      x < y
    })
    println(ll2)


    println("#" * 20)
    /**
     * 可变的List -> ListBuffer
     * 同List最大的区别就在于可以增加删除修改元素
     */
    val listB: ListBuffer[Int] = ListBuffer(1, 1, 2, 3, 3, 4, 5, 6, 9, 8, 7)

    // append 增加一个元素 参数为: elem:Int*
    // Int* 表示可变参数（可以接收任意多个Int类型的参数）
    // 将元素添加到末尾
    listB.append(1, 2, 3, 4)
    println(listB)

    listB.+=(5)
    listB.+=(6, 7, 8)
    listB += 9
    println(listB)

    // 删除元素
    // 从头开始删除
    listB.-=(4) // 按照元素从左往右匹配 将第一个匹配的值删除
    println(listB)
    listB.remove(9) // 按照索引删除
    println(listB)

    listB -= 9
    println(listB)

    // 修改元素
    listB(4) = 4
    println(listB)
    listB.update(0, -1)
    println(listB)

    // 插入元素
    listB.insert(1, 0, 0, 0, 0)
    println(listB)
    listB.insertAll(5, List(0, 1))
    println(listB)



  }

}
